﻿using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UtilZ.Dotnet.Ex.Communication.Base;
using UtilZ.Dotnet.Ex.Communication.Ports;
using UtilZ.Dotnet.Ex.Log;
using UtilZ.Dotnet.WindowsDesktopEx.Winform;

namespace DotnetWinFormApp
{
    public partial class FTestSerialPort : Form
    {
        public FTestSerialPort()
        {
            InitializeComponent();
        }

        private void FTestSerialPort_Load(object sender, EventArgs e)
        {
            if (this.DesignMode)
            {
                return;
            }

            var redirectAppenderToUI = (RedirectAppender)Loger.GetAppenderByName(null, "RedirectToUI");
            if (redirectAppenderToUI != null)
            {
                redirectAppenderToUI.RedirectOuput += RedirectAppenderToUI_RedirectOuput; ;
            }

            this.RefreshCOM();
        }

        private void RedirectAppenderToUI_RedirectOuput(object sender, RedirectOuputArgs e)
        {
            try
            {
                if (e == null || e.Item == null)
                {
                    return;
                }

                string logInfo = string.Format("{0} {1} {2}", e.Item.Time.ToString("yyyy-MM-dd HH:mm:ss"), LogConstant.GetLogLevelName(e.Item.Level), e.Item.Content);
                logControl.AddLog(logInfo, e.Item.Level);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }


        private void RefreshCOM()
        {
            try
            {
                string[] names = new SerialPortFactory().GetPortNames();
                DropdownBoxHelper.BindingIEnumerableStringToComboBox(comboBoxCOM, names, names.FirstOrDefault());
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void btnRefreshCOM_Click(object sender, EventArgs e)
        {
            this.RefreshCOM();
        }

        private SerialPortClient _serialPort = null;
        private IUnpacker _unpacker = null;
        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (this._unpacker == null)
                {
                    this._unpacker = new SerialPortTimeoutUnpacker();
                    this._unpacker.PackOutput += Unpacker_PackOutput;
                }

                if (this._serialPort == null)
                {
                    string name = DropdownBoxHelper.GetStringFromComboBox(comboBoxCOM);
                    var serialPortInitPara = new SerialPortClientInitPara(this._unpacker, name, 2400, SerialPortParity.None, 8, SerialPortStopBits.One);
                    serialPortInitPara.RecieveDataTimeout = TimeSpan.FromMilliseconds(500);
                    this._serialPort = new SerialPortClient(serialPortInitPara);
                    this._serialPort.ConnectChanged += SerialPort_ConnectChanged;
                    this._serialPort.Open();
                    btnConnect.Text = "断开";
                }
                else
                {
                    this._serialPort.Close();
                    this._serialPort.Dispose();
                    this._serialPort = null;
                    btnConnect.Text = "连接";
                }
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void SerialPort_ConnectChanged(object sender, SerialPortConnectionChangedArgs e)
        {
            if (e.Status == ConnectionStatus.Opened)
            {
                Loger.Info($"{e.SerialPortName}已连接");
            }
            else
            {
                Loger.Info($"{e.SerialPortName}已关闭");
            }
        }

        private void Unpacker_PackOutput(object sender, DataOutputArgs e)
        {
            try
            {
                string text = Encoding.ASCII.GetString(e.Data.Bytes, e.Data.Offset, e.Data.Length);
                Loger.Info(text);
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                if (this._serialPort == null)
                {
                    Loger.Warn("串口未连接");
                    return;
                }

                string cmd = txtCMD.Text.Trim();
                if (string.IsNullOrEmpty(cmd))
                {
                    Loger.Warn("命令不能为空");
                    return;
                }

                cmd = cmd + "\r";
                //if (checkBoxEnter.Checked)
                //{
                //    cmd = cmd + "\r";
                //}

                //if (checkBoxNewLine.Checked)
                //{
                //    cmd = cmd + "\n";
                //}

                byte[] buffer = Encoding.ASCII.GetBytes(cmd);
                this._serialPort.Send(buffer, 0, buffer.Length);

                Loger.Info($"向{this._serialPort.SerialPortInitPara.PortName}发送命令\"{txtCMD.Text}\"成功");
            }
            catch (Exception ex)
            {
                Loger.Error(ex);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            logControl.Clear();
        }
    }


    internal class SerialPortTimeoutUnpacker : UnpackerAbs
    {
        public SerialPortTimeoutUnpacker()
        {

        }

        protected override int PrimitiveUnPackge(IUnpackerPara unpackerPara)
        {
            throw new NotImplementedException();
        }
    }
}
